#region Summary

// 
// Owner : JackieHan 
// 
// Solution : UpdateSystem 
// 
// Project : Skomart.Update.Download 
// 
// File : UpdateManager.cs
// 
// CopyRight : Copyright © 2010-2011 Skomart Corporation, All Rights Reserved 
// 
// Summary : 更新控制
// 
// History : 
//			2010-08-03 15:14:10	    Create 
// 

#endregion

#region Using

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Skomart.Update.Config;
using Skomart.Update.Config.Client;
using Skomart.Update.Download.DownLoadService;

#endregion

namespace Skomart.Update.Download
{
    /// <summary> 
    /// 更新控制
    /// </summary>
    public class UpdateManager
    {
        private readonly ClientConfigurationManager clientManager;
        private readonly DownloadService downloadService;
        private readonly DownloadFileManager downloadFileManager;
        private readonly SystemConfigInfo serverInfo;
        private readonly string applicationDirectory;
        private readonly string backupDirectory;
        private readonly string systemName;
        private readonly string systemPath;
        private IList<HasUpdateFileInfo> hasUpdateFiles = new List<HasUpdateFileInfo>();

        public event DownloadStateChangedHandler DownloadStateChanged;
        public event EventHandler UpdateCompleted;

        public UpdateManager()
        {
            clientManager = new ClientConfigurationManager();
            downloadService = DownloadServiceManager.GetDownloadService();
            downloadFileManager = new DownloadFileManager();
            downloadFileManager.DownloadStateChanged += DownloadFileManager_DownloadStateChanged;
            var baseDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

            if (baseDirectory.Parent != null) applicationDirectory = baseDirectory.Parent.FullName;
            backupDirectory = Path.Combine(applicationDirectory, ConfigurationManager.AppSettings["backupDirectory"]);
            systemName = ConfigurationManager.AppSettings["systemName"];
            serverInfo = downloadService.GetUpdateConfig(systemName);
            systemPath = Path.Combine(applicationDirectory, ConfigurationManager.AppSettings["mainApplicationPath"]);
        }

        private void DownloadFileManager_DownloadStateChanged(object sender, DownloadStateEventArgs eventArgs)
        {
            if (DownloadStateChanged != null)
                DownloadStateChanged(sender, eventArgs);
        }

        /// <summary>
        /// 获取是否有更新
        /// </summary>
        /// <returns></returns>
        public bool HasNewUpdate()
        {
            try
            {
                hasUpdateFiles = CompareConfigManager.GetHasUpdateFiles(serverInfo.Items, clientManager.ClientFileConfigItems);
                return hasUpdateFiles.Count > 0;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        public void Update()
        {
            CloseMainApplication();

            CleanBackUpFiles();

            DeleteClientFiles(hasUpdateFiles);

            downloadFileManager.DownLoad(hasUpdateFiles, systemName);

            clientManager.UpdateToClientLog(hasUpdateFiles);

            StartMainApplication();

            if (UpdateCompleted != null)
                UpdateCompleted(this, new EventArgs());
        }

        /// <summary>
        /// 更新完成后启动主程序
        /// </summary>
        private void StartMainApplication()
        {
            var fileInfo = new FileInfo(systemPath);
            if (!fileInfo.Exists)
                throw new FileNotFoundException("the application is not exists!", systemPath);
            Process.Start(systemPath);
        }

        /// <summary>
        /// 更新开始的时候关闭主程序
        /// </summary>
        private void CloseMainApplication()
        {
            var fileInfo = new FileInfo(systemPath);
            var mainProcesses = Process.GetProcessesByName(fileInfo.Name.Replace(fileInfo.Extension, ""));
            foreach (var mainProcess in mainProcesses)
            {
                mainProcess.Kill();
            }
        }

        /// <summary>
        /// 清空备份文件夹
        /// </summary>
        private void CleanBackUpFiles()
        {
            //删除备份文件夹，创建新的备份文件夹
            if (Directory.Exists(backupDirectory))
            {
                Directory.Delete(backupDirectory, true);
            }
            Directory.CreateDirectory(backupDirectory);
        }

        /// <summary>
        /// 删除文件（移动文件到备份文件夹)
        /// </summary>
        /// <param name="hasDeleteFiles">需要删除的文件信息</param>
        private void DeleteClientFiles(IList<HasUpdateFileInfo> hasDeleteFiles)
        {
            foreach (var deleteFile in hasDeleteFiles)
            {
                if (deleteFile.OperateType == OperateType.Add) continue;
                var filePath = Path.Combine(applicationDirectory, deleteFile.File);
                var backupPath = Path.Combine(backupDirectory, deleteFile.File);
                var fileInfo = new FileInfo(backupPath);
                if ((fileInfo.Directory != null)&&(!fileInfo.Directory.Exists))
                    fileInfo.Directory.Create();
                File.Move(filePath, backupPath);
            }
        }
    }
}